package net.ericaro.neojavagengen;

import java.util.HashSet;
import java.util.Set;

import net.ericaro.neojavagen.Literals;
import net.ericaro.neojavagen.classes.InterfaceTypes;
import net.ericaro.neojavagen.interfaces.ExtendsInterfaces;
import net.ericaro.neojavagen.interfaces.InterfaceBody;
import net.ericaro.neojavagen.interfaces.InterfaceMemberDeclarations;
import net.ericaro.neojavagen.interfaces.InterfaceModifier;
import net.ericaro.neojavagen.interfaces.InterfaceModifiers;
import net.ericaro.neojavagen.interfaces.NormalInterfaceDeclaration;
import net.ericaro.neojavagen.packages.JavadocComment;
import net.ericaro.neojavagen.packages.TypeDeclaration;


public class InterfacePart extends AbstractPart{

	
	Set<PartReference> subs = new HashSet<PartReference>();
	private InterfaceMemberDeclarations interfaceMemberDeclarations;
	
	// Parsing definition
	public InterfacePart(Grammar g, String name) {
		super(g, name);
	}
	public InterfacePart withComponent(String target) {
		PartReference partReference = grammar.createPartReference(target);
		subs.add(partReference);
		
		
		
		return this;
	}
	
	
	
	public void resolve() {
		for(PartReference partReference: subs)
			partReference.addInterfaceType(getClassOrInterfaceType());
		
		
	}
	
	
	private JavadocComment generateJavadoc(){
		StringBuilder sb = new StringBuilder();
		sb.append( "<b>");
		sb.append(getSimpleTypeName());
		sb.append("</b> is any instance of  \n" + 
				" *  <ul>\n" );
		for(PartReference partReference: subs){
			sb.append(" *  <li> {@link ");
			sb.append(partReference.getClassOrInterfaceType());
			sb.append(" ").append(partReference.getSimpleTypeName());
			sb.append("</li>\n" ); 
				
		}
		sb.append(" *  </ul>\n" + 
				" * \n" + 
				" * @author eric@ericaro.net\n" + 
				" *\n" + 
				" ");
		return new JavadocComment(Literals.javadocLiteral(sb.toString()));
	}
	
	@Override
	protected TypeDeclaration getTypeDeclaration() {
		
		interfaceMemberDeclarations = new InterfaceMemberDeclarations();
		// maybe append some methods here
		
		// workaround, type declaration sadly handles null interfaces, but not empty ones (it generates an "implements" followed by nothing
		InterfaceTypes interfaceTypes = getInterfaceTypes();
		ExtendsInterfaces interfaces =null ;
		if (interfaceTypes.size() > 0 ) 
			interfaces = new ExtendsInterfaces(interfaceTypes);

		
		NormalInterfaceDeclaration normalInterfaceDeclaration = new NormalInterfaceDeclaration(generateJavadoc(),null,new InterfaceModifiers(InterfaceModifier.APUBLIC), getSimpleTypeName(), null, interfaces , new InterfaceBody(interfaceMemberDeclarations));
		
		return normalInterfaceDeclaration;
	}
	
	
	
	
	
	
	
	
	
	
	

}
